#ifndef SDK_OHOS_OHOS_SCREEN_CAPTURER_H_
#define SDK_OHOS_OHOS_SCREEN_CAPTURER_H_

#include "media/base/video_common.h"
#include "api/video/video_frame.h"
#include "common_video/ohos/ohos_egl_render_context.h"
#include "common_video/ohos/ohos_video_buffer.h"

#include <multimedia/player_framework/native_avscreen_capture.h>
#include <multimedia/player_framework/native_avscreen_capture_base.h>
#include <multimedia/player_framework/native_avscreen_capture_errors.h>
#include <native_image/native_image.h>

#include "ohos_external_audio_source_impl.h"
#include "rtc_base/buffer.h"
#include "api/peer_connection_interface.h"
#include "rtc_base/synchronization/mutex.h"

namespace webrtc {

enum CaptureState {
    CS_STOPPED,   // The capturer has been stopped or hasn't started yet.
    CS_STARTING,  // The capturer is in the process of starting. Note, it may
                    // still fail to start.
    CS_RUNNING,   // The capturer has been started successfully and is now
                    // capturing.
    CS_FAILED,    // The capturer failed to start.
    CS_OCCUPIED,  // The capturer is occupied by other process
};

class ScreenCallback {
public:
    virtual int DidCaptureVideoFrame(const webrtc::VideoFrame& frame, int capture_width, int capture_height) = 0;
    virtual void OnCaptureError(int32_t error_code) = 0;
    virtual ~ScreenCallback() {}
};

class ScreenCapturerOhos {
public:

    enum CaptureType {
        SURFACE = 0,
        BUFFER 
    };
    ScreenCapturerOhos(CaptureType type = CaptureType::SURFACE);
    ~ScreenCapturerOhos();

    bool Init();
    CaptureState Start(const cricket::VideoFormat& capture_format);
    void Stop();
    void SetCallback(ScreenCallback *screen_callback);
    bool IsRunning();
    bool IsScreencast() { return true; }
    void Release();
    void SetAudioSource(ohoswebrtc::OHOSExternalAudioSourceImpl *external_audio_source);

    void OnScreenError(int32_t error_code);
    void OnScreenStateChange(OH_AVScreenCaptureStateCode state_code);
    void OnScreenBufferAvailable(OH_AVBuffer *buffer,OH_AVScreenCaptureBufferType buffer_type, int64_t timestamp);
    void SetFrameRotation(int rotation);
private:
    /* RenderContext(EglContext EglDisplay)创建和销毁 */
    bool InitRenderContext();
    int32_t DestroyRenderContext();

    /* NativeWindow创建和销毁 */
    bool CreateNativeWindow();
    int32_t DestroyNativeWindow();

    /* NativeImage创建和销毁，需要使用eglSurface,textureID */
    bool CreateNativeImage();
    int32_t DestroyNativeImage();

    /* NativeImage回调函数 */
    static void OnNativeImageFrameAvailable(void *data);
    int32_t OnNativeFrameAvailable();

//    std::unique_ptr<EglRenderContext> renderContext_ {nullptr};
    OHNativeWindow *nativeWindow_ {nullptr};
    OH_NativeImage *nativeImage_ {nullptr};
    GLuint nativeImageTextureID_ {0U};
    EGLSurface eglSurface_ {EGL_NO_SURFACE};
    OH_OnFrameAvailableListener nativeImageFrameAvailableListener_{nullptr, nullptr};
    OhosVideoBuffer::TextureBuffer textureBuffer_;
    std::unique_ptr<EGLRenderContext> gl_context_;
private:
    cricket::VideoFormat capture_format_;
    int fps_{0};
    std::chrono::steady_clock::time_point last_frame_time_;
    int debug_log_counter_{0};
    int rotation_ = webrtc::kVideoRotation_90;
    OH_AVScreenCapture* screen_capture_{nullptr};
    CaptureType captureType_ {CaptureType::SURFACE};
    CaptureState capture_state_;
    ScreenCallback* screen_callback_ {nullptr};
    mutable webrtc::Mutex mutex_;
    ohoswebrtc::OHOSExternalAudioSourceImpl* external_audio_source_ = nullptr;
    rtc::BufferT<int16_t> captured_audio_buffer_;
    webrtc::PeerConnectionFactoryInterface* peer_connection_factory_ = nullptr;
};

} //namespace webrtc

#endif //OHOS_SCREEN_CAPTURER_H_